#ifndef _FACE_APP_H_
#define _FACE_APP_H_

#include "face_api.h"

#if (_SAFETY_MODULE_TYPE_ == _FACE_SAFETY_MODULE_) && (_SAFETY_VERIFYFUNCTION_ENABLE_)

// 发送超时                   - 250ms
#define FACE_MESSAGE_SENGING_RATED_TIME                (250ul)
// 时间补偿                   - 3s
#define FACE_MESSAGE_TIME_BIAS                         (3ul)

// 最大注册用户上限
#define FACE_NUMBER_OF_REGISTERED_USERS                (50ul)

/**
 * @brief 命令执行表
 *
 */
typedef enum
{
  FACE_WAIT_READY,                    // 等待就绪
  FACE_INTO_STANDBY,                  // 进入待机模式
  FACE_ENROLL_CANCEL,                 // 退出录取
  FACE_DELETING_USERS,                // 删除用户
  FACE_INTO_POWER_DOWM,               // 进入掉电模式
  FACE_ENROLL_FROM_FILE,              // 通过文件注册
  FACE_GET_MODULE_STATUS,             // 获取模组当前状态
  FACE_GET_SERIAL_NUMBER,             // 获取序列号
  FACE_TRANSMIT_FILE_END,             // 发送文件结束
  FACE_UPLOAD_IMAGE_DATA,             // 上传图片数据
  FACE_TRANSMIT_FILE_PACKET,          // 发送文件
  FACE_GET_IMAGE_INFORMATION,         // 获取图像属性
  FACE_EXECUTE_FACTORY_RESET,         // 恢复出厂
  FACE_GET_ALGORITHM_VERSION,         // 获取算法版本
  FACE_GET_NUMBER_OF_TEMPLATE,        // 获取模板数量
  FACE_GET_APPLICATION_VERSION,       // 获取固件版本号
  FACE_IDENTIFY_USER_PERMISSIONS,     // 鉴定用户权限
  FACE_USER_INTERACTIVE_REGISTRATION, // 注册新用户交互模式
} FaceStepsOfSending_t;

/**
 * @brief 报文解析结果
 *
 */
typedef enum
{
  FACE_EXECUTE_OVER,                // 完毕
  FACE_EXECUTE_WAIT,                // 等待
  FACE_EXECUTE_ERROR,               // 错误
  FACE_EXECUTE_RETRY,               // 重试
  FACE_EXECUTE_SUCCESS,             // 成功
  FACE_EXECUTE_USER_IS_FULL,        // 用户已满
  FACE_EXECUTE_USER_ALREADY_EXISTS, // 用户已存在
} FaceExecuteResult_t;

/**
 * @brief 硬件属性
 *
 */
typedef struct
{
  uint8_t NumberOfUser;                                        // 已注册用户数数量
  char SerialNumber[FACE_MODULE_SN_LENGTH];                    // 模组序列号
  char AlgorithmVersion[FACE_LENGTH_OF_VERSION_INFORMATION];   // 算法版本
  char ApplicationVersion[FACE_LENGTH_OF_VERSION_INFORMATION]; // 固件版本号
} FaceHardwareAttribute_t;

/**
 * @brief 本地注册状态
 *
 */
typedef struct
{
  uint16_t UserId;            // 用户编码
  uint8_t EnrollErrorCount;   // 录取失败次数
  uint8_t AdmissionDirection; // 已录取方向
} FaceRegisterStatus_t;

/**
 * @brief 文件操作状态
 *
 */
typedef struct
{
  uint8_t FileType;         // 文件类型
  uint32_t FileSize;        // 文件大小
  uint16_t TransmitterSize; // 发送数据长度
  uint32_t RequestFileSize; // 已接收文件大小
} FaceFileOperation_t;

/**
 * @brief 删除用户信息
 *
 */
typedef struct
{
  uint8_t NumberOfDelete;                          // 待删除用户数量
  uint16_t UserId[FACE_NUMBER_OF_REGISTERED_USERS]; // 删除用户编码
} FaceDeleteUserInformation_t;

/**
 * @brief 事件状态位
 *
 */
typedef struct
{
  uint16_t TempUserId;
  FaceMessageId_t MessageId;           // 期待消息类型
  FaceMessageCommand_t CommandToSend;  // 发起命令类型
  FaceStepsOfSending_t StepsOfSending; // 执行步骤
} FaceEventStatus_t;

/**
 * @brief 人脸事件状态位
 *
 */
typedef struct
{
  FaceEventStatus_t EventStatus;                     // 事件处理状态
  FaceFileOperation_t FileOperation;                 // 文件收发状态
  FaceRegisterStatus_t RegisterStatus;               // 注册状态
  FaceHardwareAttribute_t HardwareAttribute;         // 硬件属性
  FaceDeleteUserInformation_t DeleteUserInformation; // 待删除的用户信息
} FaceBitStatus_t;

/**
 * @brief 获取已注册用户数量
 *
 * @return uint8_t - 已注册用户数量
 */
extern uint8_t FaceGetTheNumberOfRegisteredUsers(void);

/**
 * @brief 获取设备序列号
 *
 * @param pSerialNumberOut - 设备序列号
 */
extern void FaceGetDeviceSerialNumber(char *pSerialNumberOut);

/**
 * @brief 获取固件版本号
 *
 * @param pVersionOut - 固件版本号
 */
extern void FaceGetApplicationVersion(char *pVersionOut);

/**
 * @brief 获取算法版本号
 *
 * @param pVersionOut - 算法版本号
 */
extern void FaceGetAlgorithmVersion(char *pVersionOut);

/**
 * @brief 构建自检对应命令的报文
 *
 * @param pMessageOut      - 构建后的数据
 * @param pSizeOut         - 构建数据长度
 * @param pResponseTimeOut - 命令响应时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FaceBuildSelfTestMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建强制进入睡眠的报文
 *
 * @param pMessageOut      - 构建后的数据
 * @param pSizeOut         - 构建数据长度
 * @param pResponseTimeOut - 命令响应时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FaceBuildForcedToGotoSleepMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建恢复出厂对应命令的报文
 *
 * @param pMessageOut      - 构建后的数据
 * @param pSizeOut         - 构建数据长度
 * @param pResponseTimeOut - 命令响应时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FaceBuildFactorySettingMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建获取特征值文件对应命令的报文
 *
 * @param pMessageOut      - 构建后的数据
 * @param pSizeOut         - 构建数据长度
 * @param pResponseTimeOut - 命令响应时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FaceBuildGetEigenvalueFileMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建本地注册持卡人对应命令的报文
 *
 * @param pMessageOut      - 构建后的数据
 * @param pSizeOut         - 构建数据长度
 * @param pResponseTimeOut - 命令响应时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FaceBuildLocalRegisterUserMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建鉴定用户权限对应命令的报文
 *
 * @param pMessageOut      - 构建后的数据
 * @param pSizeOut         - 构建数据长度
 * @param pResponseTimeOut - 命令响应时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FaceBuildUserAuthenticationMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建删除特定用户对应命令的报文
 *
 * @param pMessageOut      - 构建后的数据
 * @param pSizeOut         - 构建数据长度
 * @param pResponseTimeOut - 命令响应时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FaceBuildDeletingSpecificUsersMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建通过特征值注册用户对应命令的报文
 *
 * @param pMessageOut      - 构建后的数据
 * @param pSizeOut         - 构建数据长度
 * @param pResponseTimeOut - 命令响应时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FaceBuildRegistrationByEigenvalueMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 解析设备自检报文
 *
 * @param pDataIn        - 输入待验证的报文
 * @param DataSize       - 数据长度
 * @param ResponseResult - 响应结果
 * @return uint8_t       - 报文解析结果
 */
extern uint8_t FaceParsingSelfTestMessage(const void *pDataIn, uint16_t DataSize, uint8_t ResponseResult);

/**
 * @brief 解析设备恢复重置报文
 *
 * @param pDataIn        - 输入待验证的报文
 * @param DataSize       - 数据长度
 * @param ResponseResult - 响应结果
 * @return uint8_t       - 报文解析结果
 */
extern uint8_t FaceParsingDeviceFactorySettingMessage(const void *pDataIn, uint16_t DataSize, uint8_t ResponseResult);

/**
 * @brief 解析强制进入睡眠报文
 *
 * @param pDataIn        - 输入待验证的报文
 * @param DataSize       - 数据长度
 * @param ResponseResult - 响应结果
 * @return uint8_t       - 报文解析结果
 */
extern uint8_t FaceParsingForcedToGotoSleepMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 解析获取特征值文件报文
 *
 * @param pDataIn        - 输入待验证的报文
 * @param DataSize       - 数据长度
 * @param ResponseResult - 响应结果
 * @return uint8_t       - 报文解析结果
 */
extern uint8_t FaceParsingGetEigenvalueFileMessage(const void *pDataIn, uint16_t DataSize, uint8_t ResponseResult);

/**
 * @brief 解析本地注册用户报文
 *
 * @param pDataIn        - 输入待验证的报文
 * @param DataSize       - 数据长度
 * @param ResponseResult - 响应结果
 * @return uint8_t       - 报文解析结果
 */
extern uint8_t FaceParsingLocalRegisterUserMessage(const void *pDataIn, uint16_t DataSize, uint8_t ResponseResult);

/**
 * @brief 解析用户权限报文
 *
 * @param pDataIn        - 输入待验证的报文
 * @param DataSize       - 数据长度
 * @param ResponseResult - 响应结果
 * @return uint8_t       - 报文解析结果
 */
extern uint8_t FaceParsingUserAuthenticationMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 解析删除特定用户报文
 *
 * @param pDataIn        - 输入待验证的报文
 * @param DataSize       - 数据长度
 * @param ResponseResult - 响应结果
 * @return uint8_t       - 报文解析结果
 */
extern uint8_t FaceParsingDeletingSpecificUsersMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 解析通过特征值文件注册用户报文
 *
 * @param pDataIn        - 输入待验证的报文
 * @param DataSize       - 数据长度
 * @param ResponseResult - 响应结果
 * @return uint8_t       - 报文解析结果
 */
extern uint8_t FaceParsingRegistrationByEigenvalueMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 验证报文有效性
 *
 * @param pMessageIn     - 待验证报文
 * @param pDataOffsetOut - 指向附带数据起始地址的指针变量
 * @param pDataSizeOut   - 附带数据长度
 * @param pResultOut     - 响应结果
 * @return bool          - 验证状态（true：成功 false：失败）
 */
extern bool FaceVerifyMessageValidity(uint8_t *pMessageIn, uint8_t *pDataOffsetOut, uint16_t *pDataSizeOut, uint8_t *pResultOut);

/**
 * @brief 功能初始化
 *
 */
extern void FaceFunctionalInitialization(void);

/**
 * @brief 启动强制进入睡眠
 *
 */
extern void FaceStartForcedToGotoSleep(void);

/**
 * @brief 启动本地注册任务
 * 
 * @param WaitTime - 等待时间
 */
extern void FaceStartLocalRegisterTasks(uint8_t WaitTime);

/**
 * @brief 启动用户权限鉴定任务
 *
 */
extern void FaceStartUserAuthenticationTasks(void);

/**
 * @brief 标志待获取特征值的用户
 *
 * @param UserId - 用户编码
 */
extern void FaceMarkUserToGetEigenvalueFile(uint16_t UserId);

/**
 * @brief 启动删除用户任务
 *
 */
extern void FaceStartDeleteUserTasks(void);

/**
 * @brief 记录待删除的用户
 *
 * @param UserId - 待删除的用户
 */
extern void FaceRecordUsersToBeDeleted(uint16_t UserId);

/**
 * @brief 获取本地注册用户编码
 *
 * @return uint16_t - 用户编码
 */
extern uint16_t FaceGetLocalRegisterUserId(void);

/**
 * @brief 获取授权用户编码
 *
 * @return uint16_t - 用户编码
 */
extern uint16_t FaceGetAuthorizedUserCode(void);

#endif
#endif
